package exterminator;

import exterminator.states.HUD;
import exterminator.states.CamTransitions;
import exterminator.levels.Levels;
import com.jme3.app.SimpleApplication;
import com.jme3.font.BitmapFont;
import com.jme3.input.FlyByCamera;
import com.jme3.math.Quaternion;
import com.jme3.math.Vector2f;
import com.jme3.renderer.RenderManager;
import com.jme3.scene.Geometry;
import com.jme3.scene.Node;
import exterminator.game.Game;
import exterminator.game.Game.Lost;
import exterminator.game.controls.Hose;
import exterminator.levels.effects.Effects;
import exterminator.utils.AudioManager;
import exterminator.utils.LevelLoader;
import exterminator.utils.LevelLoader.LevelInfo;
import exterminator.utils.ScaleUtil;
import exterminator.utils.TextureManager;
import tonegod.gui.core.Screen;

/**
 * test
 * @author normenhansen
 */
public class Main extends SimpleApplication {
	Quaternion q = new Quaternion();
	Screen screen;
	FlyByCamera f;
	JmeToHarness harness;
	
	LevelLoader loader;
	
	CamTransitions camTrans;
	TextureManager texManager;
	AudioManager audioManager;
	ScaleUtil scaleManager;
	HUD hud;
	Levels levels;
	Hose hose;
	Game game;
	Effects textEffects;
	
	BitmapFont defaultFont;
	Geometry[] levelGeoms = new Geometry[4];
	
	boolean flagFromInit = false;
	boolean flagFromHarness = false;
	boolean runInit = false;
	
	float screenWidth, screenHeight;
	public static void main(String[] args) {
		Main app = new Main();
		app.start();
	}

	@Override
	public void simpleInitApp() {
		flagFromInit = true;
		
		defaultFont = assetManager.loadFont("Interface/Fonts/GameFont.fnt");
		this.setDisplayFps(true);
		this.setDisplayStatView(false);
		
		loader = new LevelLoader(this);
		loader.loadScenes("XML/scenes.xml", null);
		loader.selectScene("GigaGeek");
		loader.loadExpansions();
		
		if (!Screen.isAndroid()) {
			flagFromHarness = true;
		}
		
		runInit();
	}
	
	public JmeToHarness getHarness() {
		return this.harness;
	}
	
	public void setHarnessListener(JmeToHarness harness, float width, float height) {
		this.harness = harness;
		
		flagFromHarness = true;
		screenWidth = width;
		screenHeight = height;
		
		runInit();
	}
	
	private void runInit() {
		if (flagFromInit && flagFromHarness) {
			initScreen();
			initStates();
			initAngles();
			initModels();
			initLevels();
			initAudio();

			restartGame();
		}
	}
	
	//<editor-fold desc="Inits">
	private void initScreen() {
		if (Screen.isAndroid())
			screen = new Screen(this, "tonegod/gui/style/atlasdef/style_map.gui.xml", screenWidth, screenHeight);
		else
			screen = new Screen(this, "tonegod/gui/style/atlasdef/style_map.gui.xml");
		screen.setUseTextureAtlas(true, "tonegod/gui/style/atlasdef/atlas.png");
		screen.setUseMultiTouch(true);
		screen.setUseToolTips(true);
		inputManager.setSimulateMouse(false);
		guiNode.addControl(screen);
		
		flyCam.setDragToRotate(true);
		inputManager.setCursorVisible(true);
		flyCam.setMoveSpeed(50);
		flyCam.setEnabled(false);
	}
	private void initAngles() {
		float[] angles = new float[3];
		
		angles[0] = loader.getCurrentScene().angles[0];
		angles[1] = loader.getCurrentScene().angles[1];
		angles[2] = loader.getCurrentScene().angles[2];
		
		cam.setRotation(q.fromAngles(angles));
		
		
	}
	private void initStates() {
		scaleManager = new ScaleUtil(this, screen);
		texManager = new TextureManager(this, screen);
		hud = new HUD(this);
		stateManager.attach(hud);;
		camTrans = new CamTransitions(this);
		stateManager.attach(camTrans);
	}
	private void initModels() {
		rootNode.detachAllChildren();
		
		String path = "Models/";
		path += loader.getCurrentScene().dir;
		path += loader.getCurrentScene().model;
		
		Node n = (Node)assetManager.loadModel(path);
		rootNode.attachChild(n);
	}
	private void initLevels() {
		levels = new Levels(this, loader.getCurrentScene().winTotal);
		levelGeoms = new Geometry[loader.getLevelCount()];
		String basePath = "Models/" + loader.getCurrentScene().dir;
		Vector2f size = new Vector2f();
		
		getHUD().configGameMeter(loader.getCurrentScene().winTotal);
		
		int index = 0;
		for (LevelInfo level : loader.getCurrentScene().levels) {
			String path = basePath;
			path += level.model;
			
			Node n = (Node)assetManager.loadModel(path);
			Geometry geom = (Geometry)n.getChild(0);
			geom.move(0, 0.02f, 0);
			levelGeoms[index] = geom;
			
			levels.addDeck(geom, level.size, loader.getCurrentScene().maxBugs);
			
			index++;
		}
		
		stateManager.attach(levels);
		
		hose = new Hose(this);
		stateManager.attach(hose);
		
		textEffects = new Effects(this);
		stateManager.attach(textEffects);
		
		game = new Game(this, loader.getCurrentScene().time);
	}
	private void initAudio() {
		audioManager = new AudioManager(this, screen);
		stateManager.attach(audioManager);
		audioManager.startMusic();
	}
	//</editor-fold>
	
	public Screen getScreen() { return this.screen; }
	public LevelLoader getLevelLoader() { return this.loader; }
	public BitmapFont getDefaultFont() { return defaultFont; }
	public ScaleUtil getScaleManager() { return scaleManager; }
	public AudioManager getAudioManager() { return audioManager; }
	public TextureManager getTextureManager() { return texManager; }
	public Effects getEffects() { return textEffects; }
	public CamTransitions getCamTrans() { return camTrans; }
	public Geometry getLevelGeometry(int index) { return levelGeoms[index]; }
	public HUD getHUD() { return this.hud; }
	public Game getGame() { return this.game; }
	public Hose getHose() { return this.hose; }
	
	//<editor-fold desc="Game">
	public void startGame() {
		if (!stateManager.hasState(game))
			stateManager.attach(game);
		game.startGame();
	}
	public void restartGame() {
		levels.reset();
		game.reset();
		hud.reset();
	}
	public void endGame(Lost lost) {
		game.endGame(lost);
	}
	public void winGame() {
		game.winGame();
	}
	//</editor-fold>
	
	@Override
	public void simpleUpdate(float tpf) {
		
	}

	@Override
	public void simpleRender(RenderManager rm) {
		//TODO: add render code
	}
}
